This is the code used for data analysis reported in Chapter 5 of the dissertation “Multimodal annotation and analysis of a Narrative problem solving task in English, Idi, and Russian”. It analyzes pointing gesture forms and their spoken affiliates. Specifically, the script contains multiple Multiple Correspondence Analyses (MCA) in English and Russian used to uncover the underlying relationships and patterns among the variables.The analysis encompasses variables capturing pointing gesture forms — such as hand shape, palm orientation, contact with the target, and trajectory of movement — alongside annotations for nouns, verbs, and demonstratives. By extracting eigenvalues from the MCA, the script quantifies how much variance each dimension explains, utilizing a scree plot for visualization to assist in identifying the dimensions of significance.

Load packages

library(here) 
library(dplyr)
library(tidyr)
library(stringr)
library(FactoMineR)
library(factoextra)
library(patchwork)
library(ggforce)

Load and clean df for English nouns

eng.nouns.pr <- read.delim2(here("data", "eng.nouns.w.points-processed.csv"), sep = ";") %>%
  separate(gest, c("pgb", "shape", "cont", "traj", "orient")) %>%
  mutate(semcl = case_when(str_detect(conc,"abs")   ~ "abstract",
                           str_detect(anim, "inanim") & str_detect(conc, "conc") ~ "material",
                           str_detect(anim, "anim") & str_detect(conc, "conc") ~ "animate",
                        TRUE ~ "na")) %>%
  mutate(emb=recode(emb,
                    `def` = "def.art",
                    `indef`="indef.art",
                    `dem`="demonstr",
                    `pp`="pers.pron",
                    `other`="no.modif",
                    )) %>%
  mutate(shape=recode(shape,
                    `other` = "other.shape")) %>%
  select(2:5,9,12:13) %>%
  mutate_if(is.character,as.factor)

summary(eng.nouns.pr)
##          shape           cont         traj         orient    feats   
##  index      :79   contact  :59   complex:57   down    :111   pl: 19  
##  other.shape:19   nocontact:67   simple :69   up      :  3   sg:107  
##  palm       :28                               vertical: 12           
##                                                                      
##                                                                      
##         emb          semcl   
##  def.art  :58   abstract:30  
##  demonstr :15   animate :51  
##  indef.art:17   material:45  
##  no.modif :15                
##  pers.pron:21

Run analysis

eng.n.mca <- MCA(eng.nouns.pr, graph = FALSE)

Get eigenvalues

eng.n.mca.val <- get_eigenvalue(eng.n.mca)
head(eng.n.mca.val)
##       eigenvalue variance.percent cumulative.variance.percent
## Dim.1  0.2556130        13.763775                    13.76378
## Dim.2  0.2279846        12.276096                    26.03987
## Dim.3  0.2001100        10.775152                    36.81502
## Dim.4  0.1835449         9.883186                    46.69821
## Dim.5  0.1616560         8.704553                    55.40276
## Dim.6  0.1480509         7.971972                    63.37473

Scree Plot

fviz_screeplot(eng.n.mca, addlabels = TRUE, ylim = c(0, 45))

## Quality of Representation

eng.n.categories_cos2 <- eng.n.mca$var$cos2

# The 'cos2' for the individuals
individuals_cos2 <- eng.n.mca$ind$cos2
knitr::kable(eng.n.categories_cos2[, 1:2], caption = "Squared cosines for the first two dimensions of categories")
Squared cosines for the first two dimensions of categories
Dim 1 Dim 2
index 0.0199291 0.0424407
other.shape 0.1110559 0.1128664
palm 0.2034558 0.2796453
contact 0.0938058 0.1131152
nocontact 0.0938058 0.1131152
complex 0.2122907 0.1437974
simple 0.2122907 0.1437974
down 0.0058938 0.4206491
up 0.0708005 0.0750137
vertical 0.0496798 0.3286472
pl 0.1101900 0.1019985
sg 0.1101900 0.1019985
def.art 0.1081774 0.0018444
demonstr 0.1018764 0.1574390
indef.art 0.0424084 0.2653359
no.modif 0.4475494 0.0638252
pers.pron 0.0027960 0.0012029
abstract 0.3149239 0.0517249
animate 0.2937502 0.0004331
material 0.0031788 0.0327043

Biplot with categories of different variables

fviz_mca_biplot(eng.n.mca, 
               repel = TRUE, # Avoid text overlapping (slow if many point)
               ggtheme = theme_minimal())

# Final plot for English nouns

mca.plot.eng <- fviz_mca_var(eng.n.mca,
                               col.var = "contrib",
                               gradient.cols = c("#183A5A", "#EFB758", "#C34129", "#8B0000"), 
                               repel = TRUE, pointsize=0.5) # Avoid text overlapping

mca.eng.plot.noun.print.fin <- mca.plot.eng + 
  geom_point(aes(size = cos2, color=contrib)) +
  guides(size = FALSE) +
  theme(text=element_text(size=12),
        axis.title = element_text(),
        legend.position="bottom") +
  labs(y = "Dimention 2 (12.2%)", x = "Dimention 1 (13.7%)", color = "Contribution", title = "English") +
  ggforce::geom_ellipse(aes(x0 = 1.25, y0 = 1.1, a = 1.1, b = 0.9, angle = pi / 2.5), 
               color="grey") +
  ggforce::geom_ellipse(aes(x0 = 0.75, y0 = -0.7, a = 0.2, b = 0.5, angle = pi / 5), 
               color="grey") +
  ggforce::geom_ellipse(aes(x0 = -0.8, y0 = -1, a = 0.5, b = 0.7, angle = pi / 1), 
               color="grey")
## Warning: The `<scale>` argument of `guides()` cannot be `FALSE`. Use "none" instead as
## of ggplot2 3.3.4.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
mca.eng.plot.noun.print.fin

## Load and clean Russian nouns df

rus.nouns.pr <- read.delim2(here("data", "rus.nouns.w.points-processed.csv"), encoding = "UTF-8", sep = ";") %>%
  separate(Gest, c("pgb", "shape", "cont", "traj", "orient")) %>%
  mutate_if(is.character, str_to_lower) %>%
  mutate(modifier=recode(modifier,
                    `dem`="demonstr",
                    `pp`="poss.pron",
                    `no`="no.modif",
                    `indef`="no.modif",
                    `other`="other.modif",
                    )) %>%
  mutate(shape=recode(shape,
                    `other`="other.shape")) %>%
  select(2:5,11:13) %>%
  mutate_if(is.character,as.factor)

summary(rus.nouns.pr)
##          shape            cont          traj          orient    num     
##  index      :149   contact  :118   complex: 81   down    :158   pl: 27  
##  other.shape: 14   nocontact: 94   simple :131   up      : 18   sg:185  
##  palm       : 49                                 vertical: 36           
##                                                                         
##        anim           modifier  
##  abstract:49   demonstr   : 56  
##  anim    :99   no.modif   :131  
##  material:64   other.modif: 13  
##                poss.pron  : 12

Run analysis

rus.n.mca <- MCA(rus.nouns.pr, graph = FALSE)

Get eigenvalues

rus.n.mca.val <- get_eigenvalue(rus.n.mca)
head(rus.n.mca.val)
##       eigenvalue variance.percent cumulative.variance.percent
## Dim.1  0.2557877        14.920947                    14.92095
## Dim.2  0.2195224        12.805472                    27.72642
## Dim.3  0.1888231        11.014683                    38.74110
## Dim.4  0.1663907         9.706123                    48.44722
## Dim.5  0.1634222         9.532961                    57.98019
## Dim.6  0.1413013         8.242576                    66.22276

Scree Plot

fviz_screeplot(rus.n.mca, addlabels = TRUE, ylim = c(0, 45))

## Quality of Representation

rus.n.categories_cos2 <- rus.n.mca$var$cos2

# The 'cos2' for the individuals
individuals_cos2 <- rus.n.mca$ind$cos2
knitr::kable(rus.n.categories_cos2[, 1:2], caption = "Squared cosines for the first two dimensions of categories")
Squared cosines for the first two dimensions of categories
Dim 1 Dim 2
index 0.4089129 0.0745065
other.shape 0.0081184 0.0399044
palm 0.5570034 0.0317669
contact 0.1343692 0.0013808
nocontact 0.1343692 0.0013808
complex 0.0859367 0.4126713
simple 0.0859367 0.4126713
down 0.2431241 0.0000731
up 0.0000971 0.0165592
vertical 0.3190702 0.0111198
pl 0.0184676 0.5924419
sg 0.0184676 0.5924419
abstract 0.4095130 0.0680753
anim 0.2042917 0.1087854
material 0.0092983 0.3576428
demonstr 0.1824232 0.0007307
no.modif 0.0795316 0.0194440
other.modif 0.0737296 0.0326985
poss.pron 0.0036025 0.0246593

Biplot with categories of different variables

fviz_mca_biplot(rus.n.mca, 
               repel = TRUE, # Avoid text overlapping (slow if many point)
               ggtheme = theme_minimal())

## Final plot for Russian nouns

mca.plot.rus <- fviz_mca_var(rus.n.mca,
                               col.var = "contrib",
                               gradient.cols = c("#183A5A", "#EFB758", "#C34129", "#8B0000"), 
                               repel = TRUE, pointsize=0.5) # Avoid text overlapping

mca.noun.plot.print.fin.rus <- mca.plot.rus + 
  geom_point(aes(size = cos2, color=contrib)) +
  guides(size = FALSE) +
  theme(text=element_text(size=12),
        axis.title = element_text(),
        legend.position="bottom") +
  labs(y = "Dimention 2 (12.8%)", x = "Dimention 1 (14.9%)", color = "Contribution", title = "Russian") +
  ggforce::geom_ellipse(aes(x0 = 1.2, y0 = -0.5, a = 0.9, b = 0.3, angle = pi / 2.5), 
               color="grey") +
  ggforce::geom_ellipse(aes(x0 = 0.4, y0 = 1.3, a = 0.2, b = 1, angle = pi / 1), 
               color="grey") +
  ggforce::geom_ellipse(aes(x0 = -0.1, y0 = -0.4, a = 0.5, b = 0.2, angle = pi / 2.5), 
               color="grey")

mca.noun.plot.print.fin.rus

Save English and Russian noun plots next to each other

png(here("figures", "fppt-eng-mca-nouns-plot.png"), width = 25, height = 15, units = "cm", res = 1000)
mca.eng.plot.noun.print.fin + mca.noun.plot.print.fin.rus
dev.off()
## quartz_off_screen 
##                 2
pdf(here("figures", "fppt-eng-mca-nouns-plot.pdf"), width = 8, height = 6)
mca.eng.plot.noun.print.fin + mca.noun.plot.print.fin.rus
dev.off()
## quartz_off_screen 
##                 2

Load in English verbs df

eng.verbs.pr <- read.delim2(here("data", "eng.verbs.w.points-processed.csv"), sep = ";") %>%
   mutate_at(8:11, str_to_lower) %>%
  separate(1, c("pgb", "shape", "cont", "traj", "orient")) %>%
  mutate(shape=recode(shape,
                    `other` = "other.shape")) %>%
  mutate(Event=recode(Event,
                    `card` = "card.description",
                    `meta` = "task.management")) %>%
  select(2:5,12:15) %>%
  mutate_if(is.character,as.factor)

summary(eng.verbs.pr)
##          shape           cont         traj         orient   
##  index      :92   contact  :74   complex:54   down    :100  
##  other.shape: 9   nocontact:47   simple :67   up      :  3  
##  palm       :20                               vertical: 18  
##               asp              Trans                 Event         Process  
##  non.progressive:73   intransitive:29   card.description:88   material :45  
##  progressive    :48   transitive  :92   task.management :33   mental   :76  
## 

Run analysis

eng.v.mca <- MCA(eng.verbs.pr, graph = FALSE)

Get eigenvalues

eng.v.mca.val <- get_eigenvalue(eng.v.mca)
head(eng.v.mca.val)
##       eigenvalue variance.percent cumulative.variance.percent
## Dim.1  0.2737349        21.898794                    21.89879
## Dim.2  0.1923179        15.385431                    37.28422
## Dim.3  0.1623009        12.984074                    50.26830
## Dim.4  0.1487771        11.902169                    62.17047
## Dim.5  0.1160437         9.283498                    71.45397
## Dim.6  0.1040409         8.323271                    79.77724

Scree Plot

fviz_screeplot(eng.v.mca, addlabels = TRUE, ylim = c(0, 45))

## Biplot with categories of different variables

fviz_mca_biplot(eng.v.mca, 
               repel = TRUE, # Avoid text overlapping (slow if many point)
               ggtheme = theme_minimal())

## Final plot

mca.plot.eng.v <- fviz_mca_var(eng.v.mca,
                               axes = c(1, 2),
                               col.var = "contrib",
                               gradient.cols = c("#183A5A", "#EFB758", "#C34129", "#8B0000"), 
                               repel = TRUE, pointsize=0.5) # Avoid text overlapping

mca.eng.plot.print.fin.v <- mca.plot.eng.v + 
  geom_point(aes(size = cos2, color=contrib)) +
  guides(size = FALSE) +
  theme(text=element_text(size=12),
        axis.title = element_text(),
        legend.position="bottom") +
  labs(y = "Dimention 2 (15.4%)", x = "Dimention 1 (21.9%)", color = "Contribution", title = "English") +
  ggforce::geom_ellipse(aes(x0 = 1, y0 = -0.1, a = 0.8, b = 0.9, angle = pi / 2.5), 
               color="grey")  +
  ggforce::geom_ellipse(aes(x0 = -0.85, y0 = -0.1, a = 1.4, b = 0.45, angle = pi / 2.5), 
               color="grey")
    
mca.eng.plot.print.fin.v

## Load in Russian Verbs

rus.verbs.pr <- read.delim2(here("data", "rus.verbs.w.points-processed.csv"), encoding = "UTF-8", sep = ";") %>%
  separate(1, c("pgb", "shape", "cont", "traj", "orient")) %>%
  mutate(num = case_when(str_detect(feats,"Number=Sing") ~ "sg",
                         str_detect(feats, "Number=Plur") ~ "pl",
         TRUE ~ "sg")) %>%
  mutate_if(is.character, str_to_lower) %>%
  select(2:5,11:14) %>%
  mutate(shape=recode(shape,
                    `other`="other.shape")) %>%
  mutate(use=recode(use,
                    `card` = "card.description",
                    `task` = "task.management")) %>%
  mutate_if(is.character,as.factor) 
  
summary(rus.verbs.pr)
##          shape            cont         traj          orient        trans    
##  index      :117   contact  :92   complex: 71   down    :130   intrans: 41  
##  other.shape: 14   nocontact:79   simple :100   up      : 16   trans  :130  
##  palm       : 40                                vertical: 25                
##                                                                             
##           v.form                 use         semantics 
##  imperative  : 4   card.description:148   material:86  
##  imperfective:80   task.management : 23   mental  :85  
##  infinitive  : 8                                       
##  perfective  :79

Analyse verbs

rus.v.mca <- MCA(rus.verbs.pr, graph = FALSE)

Get eigenvalues

rus.v.mca.val <- get_eigenvalue(rus.v.mca)
head(rus.v.mca.val)
##       eigenvalue variance.percent cumulative.variance.percent
## Dim.1  0.2701257        18.008380                    18.00838
## Dim.2  0.1900246        12.668308                    30.67669
## Dim.3  0.1709563        11.397087                    42.07377
## Dim.4  0.1494249         9.961663                    52.03544
## Dim.5  0.1344482         8.963212                    60.99865
## Dim.6  0.1271454         8.476359                    69.47501

Scree Plot

fviz_screeplot(rus.v.mca, addlabels = TRUE, ylim = c(0, 45))

Biplot with categories of different variables

fviz_mca_biplot(rus.v.mca, 
               repel = TRUE, # Avoid text overlapping (slow if many point)
               ggtheme = theme_minimal())

## Russian verbs plot

mca.plot.rus.v <- fviz_mca_var(rus.v.mca,
                               col.var = "contrib",
                               gradient.cols = c("#183A5A", "#EFB758", "#C34129", "#8B0000"), 
                               repel = TRUE, pointsize=0.5) # Avoid text overlapping

mca.verb.plot.print.fin.rus.v <- mca.plot.rus.v + 
  geom_point(aes(size = cos2, color=contrib)) +
  guides(size = FALSE) +
  theme(text=element_text(size=12),
        axis.title = element_text(),
        legend.position="bottom") +
  labs(y = "Dimention 2 (12.7%)", x = "Dimention 1 (18.1%)", color = "Contribution", title = "Russian") +
  ggforce::geom_ellipse(aes(x0 = 3, y0 = 1, a = 2, b = 0.9, angle = pi / 1), 
               color="grey")

mca.verb.plot.print.fin.rus.v

## Save plots

png(here("figures", "fppt-rus-eng-mca-verbs-plot.png"), width = 25, height = 15, units = "cm", res = 1000)
mca.eng.plot.print.fin.v + mca.verb.plot.print.fin.rus.v
dev.off()
## quartz_off_screen 
##                 2
pdf(here("figures", "ffppt-rus-eng-mca-verbs-plot.pdf"), width = 8, height = 6)
mca.eng.plot.print.fin.v + mca.verb.plot.print.fin.rus.v
dev.off()
## quartz_off_screen 
##                 2

Demonstratives English load in

eng.dem.pr <- read.delim2(here("data", "eng.dem.w.points-processed.csv"), sep = ";") %>%
  separate(1, c("pgb", "shape", "cont", "traj", "orient")) %>%
  select(2:5,12) %>%
  mutate_if(is.character,as.factor)

summary(eng.dem.pr$class)
##   dem_p_prox loc_adv_dist loc_adv_prox   pp_1st_2nd        pp_pl        pp_sg 
##           23            7            8            7           17          103

Run analysis

eng.dem.mca <- MCA(eng.dem.pr, graph = FALSE)
eng.dem.mca.val <- get_eigenvalue(eng.dem.mca)
head(eng.dem.mca.val)
##       eigenvalue variance.percent cumulative.variance.percent
## Dim.1  0.3013688        13.698581                    13.69858
## Dim.2  0.2932196        13.328162                    27.02674
## Dim.3  0.2565960        11.663455                    38.69020
## Dim.4  0.2265471        10.297596                    48.98779
## Dim.5  0.2018272         9.173965                    58.16176
## Dim.6  0.1961635         8.916522                    67.07828

Scree Plot

fviz_screeplot(eng.dem.mca, addlabels = TRUE, ylim = c(0, 45))

## Biplot with categories of different variables

fviz_mca_biplot(eng.dem.mca, 
               repel = TRUE, # Avoid text overlapping (slow if many point)
               ggtheme = theme_minimal())

## Final plot

mca.plot.eng.dem <- fviz_mca_var(eng.dem.mca,
                               col.var = "contrib",
                               gradient.cols = c("#183A5A", "#EFB758", "#C34129", "#8B0000"), 
                               repel = TRUE, pointsize=0.5) # Avoid text overlapping
mca.eng.plot.print.fin.dem <- mca.plot.eng.dem + 
  geom_point(aes(size = cos2, color=contrib)) +
  guides(size = FALSE) +
  theme(text=element_text(size=12),
        axis.title = element_text(),
        legend.position="bottom") +
  labs(y = "Dimention 2 (13.3%)", x = "Dimention 1 (13.7%)", color = "Contribution", title = "English")
    
mca.eng.plot.print.fin.dem

## Load demonstratives and person pronouns Russian

rus.dem.pr <- read.delim2(here("data", "rus.dem.w.points-processed.csv"), encoding = "UTF-8", sep = ";") %>%
  separate(1, c("pgb", "shape", "cont", "traj", "orient")) %>%
  mutate_if(is.character, str_to_lower) %>%
  mutate(shape=recode(shape,
                    `other`="other.shape",
                    `iindex`="index")) %>%
  mutate(orient=recode(orient,
                    `dow`="down")) %>%
  mutate(class=recode(class,
                    `loc_adv_pr`="loc_adv_prox",
                    `pp_1st_pl`="pp_1st_2nd",
                    `pp_1st_sg`="pp_1st_2nd",
                    `pp_2nd`="pp_1st_2nd",
                    `all`="other",
                    `evid_adv`="other",
                    `temporal`="other")) %>%
  select(2:5,11) %>%
  filter(!class %in% c("other", "pp_1st_2nd")) %>%
  mutate_if(is.character,as.factor)

summary(rus.dem.pr$class)
##   dem_p_dist   dem_p_prox loc_adv_dist loc_adv_prox        pp_pl        pp_sg 
##            9           10           16           36           33          130

Analyse dem and pp

rus.dem.mca <- MCA(rus.dem.pr, graph = FALSE)

Get eigenvalues

rus.dem.mca.val <- get_eigenvalue(rus.dem.mca)
head(rus.dem.mca.val)
##       eigenvalue variance.percent cumulative.variance.percent
## Dim.1  0.3500636        15.911983                    15.91198
## Dim.2  0.2825796        12.844525                    28.75651
## Dim.3  0.2469230        11.223773                    39.98028
## Dim.4  0.2101107         9.550486                    49.53077
## Dim.5  0.2008731         9.130598                    58.66136
## Dim.6  0.1997556         9.079799                    67.74116

Scree Plot

fviz_screeplot(rus.dem.mca, addlabels = TRUE, ylim = c(0, 45))

## Biplot with categories of different variables

fviz_mca_biplot(rus.dem.mca, 
               repel = TRUE, # Avoid text overlapping (slow if many point)
               ggtheme = theme_minimal())

Final plot Russian

mca.plot.rus.dem <- fviz_mca_var(rus.dem.mca,
                               col.var = "contrib",
                               gradient.cols = c("#183A5A", "#EFB758", "#C34129", "#8B0000"), 
                               repel = TRUE, pointsize=0.5) # Avoid text overlapping

mca.noun.plot.print.fin.rus.dem <- mca.plot.rus.dem + 
  geom_point(aes(size = cos2, color=contrib)) +
  guides(size = FALSE) +
  theme(text=element_text(size=12),
        axis.title = element_text(),
        legend.position="bottom") +
  labs(y = "Dimention 2 (12.8%)", x = "Dimention 1 (15.9%)", color = "Contribution", title = "Russian")

mca.noun.plot.print.fin.rus.dem

## Save plot Russian and English

png(here("figures", "fppt-rus-eng-mca-dems-plot.png"), width = 25, height = 15, units = "cm", res = 1000)
mca.eng.plot.print.fin.dem + mca.noun.plot.print.fin.rus.dem
dev.off()
## quartz_off_screen 
##                 2
pdf(here("figures", "fppt-rus-eng-mca-dems-plot.pdf"), width = 8, height = 6)
mca.eng.plot.print.fin.dem + mca.noun.plot.print.fin.rus.dem
dev.off()
## quartz_off_screen 
##                 2

Session info

sessionInfo()
## R version 4.3.2 (2023-10-31)
## Platform: aarch64-apple-darwin20 (64-bit)
## Running under: macOS Sonoma 14.4
## 
## Matrix products: default
## BLAS:   /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRblas.0.dylib 
## LAPACK: /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRlapack.dylib;  LAPACK version 3.11.0
## 
## locale:
## [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
## 
## time zone: Europe/Berlin
## tzcode source: internal
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
## [1] ggforce_0.4.1    patchwork_1.2.0  factoextra_1.0.7 ggplot2_3.4.4   
## [5] FactoMineR_2.9   stringr_1.5.1    tidyr_1.3.0      dplyr_1.1.4     
## [9] here_1.0.1      
## 
## loaded via a namespace (and not attached):
##  [1] gtable_0.3.4         xfun_0.41            bslib_0.6.1         
##  [4] htmlwidgets_1.6.4    rstatix_0.7.2        ggrepel_0.9.4       
##  [7] lattice_0.21-9       vctrs_0.6.5          tools_4.3.2         
## [10] generics_0.1.3       sandwich_3.1-0       tibble_3.2.1        
## [13] fansi_1.0.5          highr_0.10           cluster_2.1.4       
## [16] pkgconfig_2.0.3      Matrix_1.6-5         scatterplot3d_0.3-44
## [19] lifecycle_1.0.4      farver_2.1.1         compiler_4.3.2      
## [22] munsell_0.5.0        leaps_3.1            codetools_0.2-19    
## [25] carData_3.0-5        htmltools_0.5.7      sass_0.4.7          
## [28] yaml_2.3.7           crayon_1.5.2         car_3.1-2           
## [31] ggpubr_0.6.0         pillar_1.9.0         jquerylib_0.1.4     
## [34] MASS_7.3-60          flashClust_1.01-2    DT_0.31             
## [37] cachem_1.0.8         abind_1.4-5          multcomp_1.4-25     
## [40] tidyselect_1.2.0     digest_0.6.33        mvtnorm_1.2-4       
## [43] stringi_1.8.2        purrr_1.0.2          labeling_0.4.3      
## [46] splines_4.3.2        polyclip_1.10-6      rprojroot_2.0.4     
## [49] fastmap_1.1.1        grid_4.3.2           colorspace_2.1-0    
## [52] cli_3.6.1            magrittr_2.0.3       survival_3.5-7      
## [55] utf8_1.2.4           broom_1.0.5          TH.data_1.1-2       
## [58] withr_2.5.2          backports_1.4.1      scales_1.3.0        
## [61] estimability_1.4.1   rmarkdown_2.25       emmeans_1.8.9       
## [64] ggsignif_0.6.4       zoo_1.8-12           coda_0.19-4         
## [67] evaluate_0.23        knitr_1.45           rlang_1.1.2         
## [70] Rcpp_1.0.11          xtable_1.8-4         glue_1.6.2          
## [73] tweenr_2.0.2         rstudioapi_0.15.0    jsonlite_1.8.7      
## [76] R6_2.5.1             multcompView_0.1-9